﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Nutrapp.Models;
using System.Transactions;

namespace Nutrapp.DBAL
{
    public class DBRecipeRepository : IRecipeRepository
    {
        private NutrappDataContext context = new NutrappDataContext();
        private IIngredientRepository ingredientRepo;

        public DBRecipeRepository(IIngredientRepository ingRepo)
        {
            ingredientRepo = ingRepo;
        }
        public IEnumerable<Recipe> Recipes
        {
            get { return context.Recipes; }
        }

        public string[] GetRecipeNameList(string name)
        {
            name.Trim();
            string[] keyWords = name.Split(' ');
            return keyWords;
        }

        public void SaveRecipe(RecipeModel recipe)
        {
            //TODO insert key words for recipe

            Recipe rec;
            if (recipe.ID == 0)
            {
                rec = new Recipe();
                rec.Picture = recipe.Picture;
            }
            else
            {
                rec = context.Recipes.FirstOrDefault(r => r.ID == recipe.ID); //get recipe from data base
                foreach (var r in rec.Recipe_Ingredients)
                {
                    context.Recipe_Ingredients.DeleteOnSubmit(r); //delete old ingredients
                }
                if (recipe.Picture != null)
                {
                    rec.Picture = recipe.Picture;
                }
                
                foreach (var item in rec.Recipe_KeyWords)
                {
                    context.Recipe_KeyWords.DeleteOnSubmit(item); //delete old recipe name realted key words
                }
                
            }
            rec.Name = recipe.Name;
            rec.Cost = recipe.Cost;
            
            rec.Instruction = recipe.Instruction;
            rec.Recipe_Ingredients.AddRange(recipe.IngredientLines);
            rec.Rating = recipe.Rating;

            setNutritionToRecipe(recipe, rec); //calculate nutrition for recipe

            //insert recipe
            if (recipe.ID == 0) // for create recipe
            {
                context.Recipes.InsertOnSubmit(rec);
                context.SubmitChanges();
            }
            
            //insert key word for recipe name
            string[] recipeNameList = GetRecipeNameList(recipe.Name);
            for (int i = 0; i < recipeNameList.Length; i++)
            {
                RecipeNameKeyWord kw = context.RecipeNameKeyWords.FirstOrDefault(j => j.KeyWord.Equals(recipeNameList[i].ToLower()));
                Recipe_KeyWord rk = new Recipe_KeyWord() { RID = rec.ID };
                if (kw == null)
                {
                    //insert the name key word with lowercase
                    RecipeNameKeyWord nkw = new RecipeNameKeyWord() { KeyWord = recipeNameList[i].ToLower() };
                    context.RecipeNameKeyWords.InsertOnSubmit(nkw);
                    context.SubmitChanges();
                    rk.KID = nkw.ID;
                }
                else
                {
                    rk.KID = kw.ID;
                }
                context.Recipe_KeyWords.InsertOnSubmit(rk);

            }

            context.SubmitChanges();

        }

        public Recipe setNutritionToRecipe(RecipeModel model, Recipe rec)
        {
             //set nutrition value to 0
            
                rec.Protein = 0;
                rec.Fat = 0;
                rec.Carbohydrate = 0;
                rec.Calories = 0;
            
            
            foreach (var item in model.IngredientLines) //sum the nutrition data for each ingredient line for four category(protein, fat...)
            {
                Ingredient ingredient = ingredientRepo.Ingredients.FirstOrDefault(i => i.ID == item.IID);
                
                if (item.UID == 4) //check if the unit is piece, if it is, convert piece to gram
                {
                    int? amount = ingredient.PeiceToGram * item.Quantity;
                    rec.Protein += amount * ingredient.Protein / 100;
                    rec.Fat += amount * ingredient.Fat / 100;
                    rec.Carbohydrate += amount * ingredient.Carbohydrate / 100;
                    rec.Calories += amount * ingredient.Calories / 100;
                }
                else if (item.UID == 1 || item.UID == 2)
                {
                    int kgToGram = 1;
                    if (item.UID == 2)
                    {
                        kgToGram = 1000;
                    }
                    rec.Protein += item.Quantity * ingredient.Protein * kgToGram / 100;
                    rec.Fat += item.Quantity * ingredient.Fat * kgToGram / 100;
                    rec.Carbohydrate += item.Quantity * ingredient.Carbohydrate * kgToGram / 100;
                    rec.Calories += item.Quantity * ingredient.Calories * kgToGram / 100;
                }
                //TODO missing combine liquid and solid food nutrition
            }
            return rec;
        }
        public Recipe GetRecipe(int id)
        {


            Recipe recipe = context.Recipes.FirstOrDefault(r => r.ID == id);

            return recipe;

        }


        public int DeleteRecipe(int id)
        {
            Recipe rec = context.Recipes.Where(c => c.ID == id).SingleOrDefault();
            //delete ingredient lines
            foreach (var item in rec.Recipe_Ingredients)
            {
                context.Recipe_Ingredients.DeleteOnSubmit(item);
            }
            //delete recipe key words
            context.Recipe_KeyWords.DeleteAllOnSubmit(rec.Recipe_KeyWords);

            context.Recipes.DeleteOnSubmit(rec);
            context.SubmitChanges();
            return rec.ID;
        }



    }
}